
#ifndef VANTIDEL_CPP_CLASS_H
#define VANTIDEL_CPP_CLASS_H

#include "common.h"
#include "utils.h"
#include "ObjHeader.h"
#include "ObjString.h"
#include "ObjFn.h"

// ValueType -> Value
#define VT_TO_VALUE(vt) ((Value){vt, {0}})

// Value 《==》 *
#define BOOL_TO_VALUE(boolean) (boolean ? VT_TO_VALUE(VT_TRUE) : VT_TO_VALUE(VT_FALSE))
#define VALUE_TO_BOOL(value) ((value).type == VT_TRUE ? true : false)
#define NUM_TO_VALUE(num) ((Value){VT_NUM, {num}})
#define VALUE_TO_NUM(value) value.num
#define OBJ_TO_VALUE(objPtr) ({ \
   Value value; \
   value.type = VT_OBJ; \
   value.objHeader = (ObjHeader*)(objPtr); \
   value; \
})
#define VALUE_TO_OBJ(value) (value.objHeader)
#define VALUE_TO_OBJSTR(value) ((ObjString*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJFN(value) ((ObjFn*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJRANGE(value) ((ObjRange*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJINSTANCE(value) ((ObjInstance*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJLIST(value) ((ObjList*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJMAP(value) ((ObjMap*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJCLOSURE(value) ((ObjClosure*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJTHREAD(value) ((ObjThread*)VALUE_TO_OBJ(value))
#define VALUE_TO_OBJMODULE(value) ((ObjModule*)VALUE_TO_OBJ(value))
#define VALUE_TO_CLASS(value) ((Class*)VALUE_TO_OBJ(value))

// 判断<value>是否为某种特定的结构 -> Value is *
#define VALUE_IS_UNDEFINED(value) ((value).type == VT_UNDEFINED)
#define VALUE_IS_NULL(value) ((value).type == VT_NULL)
#define VALUE_IS_TRUE(value) ((value).type == VT_TRUE)
#define VALUE_IS_FALSE(value) ((value).type == VT_FALSE)
#define VALUE_IS_NUM(value) ((value).type == VT_NUM)
#define VALUE_IS_OBJ(value) ((value).type == VT_OBJ)
#define VALUE_IS_CERTAIN_OBJ(value, objType) (VALUE_IS_OBJ(value) && VALUE_TO_OBJ(value)->type == objType)
#define VALUE_IS_OBJSTR(value) (VALUE_IS_CERTAIN_OBJ(value, OT_STRING))
#define VALUE_IS_OBJINSTANCE(value) (VALUE_IS_CERTAIN_OBJ(value, OT_INSTANCE))
#define VALUE_IS_OBJCLOSURE(value) (VALUE_IS_CERTAIN_OBJ(value, OT_CLOSURE))
#define VALUE_IS_OBJRANGE(value) (VALUE_IS_CERTAIN_OBJ(value, OT_RANGE))
#define VALUE_IS_CLASS(value) (VALUE_IS_CERTAIN_OBJ(value, OT_CLASS))
#define VALUE_IS_0(value) (VALUE_IS_NUM(value) && (value).num == 0)

typedef enum {
    MT_NONE,            // 空方法类型,并不等同于undefined
    MT_PRIMITIVE,       // 在vm中用c实现的原生方法
    MT_SCRIPT,          // 脚本中定义的方法
    MT_FN_CALL,         // 有关函数对象的调用方法,用来实现函数重载
} MethodType; // 方法类型

// 原生方法指针
/** Primitive
 * @description 函数指针 -> 指向原生方法的指针
 * @param vm:VM* -> 指向虚拟机对象
 * @param args:Value* -> 参数列表
 */
typedef bool (*Primitive)(VM *vm, Value *args);

typedef struct {
    MethodType type;  // union中的值由type的值决定
    union {
        // 指向脚本方法所关联的c实现
        Primitive primFn;

        // 指向脚本代码编译后的ObjClosure或ObjFn
        ObjClosure *obj;
    };
} Method;

DECLARE_BUFFER_TYPE(Method)

class Class {
public:
    ObjHeader objHeader;
    Class *superClass = nullptr;        // 父类
    uint32_t fieldNum = 0;        // 本类的字段数,包括基类的字段数
    MethodBuffer methods{};     // 本类的方法
    ObjString *name = nullptr;          // 类名

    Class() = default;

    Class(VM *vm, const char *name, uint32_t fieldNum);

    static Class *NewRawClass(VM *vm, const char *name, uint32_t fieldNum);

    static Class* NewClass(VM* vm, ObjString* className, uint32_t fieldNum, Class* superClass);

    static Class *GetClassOfObj(VM *vm, Value object);
}; // 对象类

typedef union {
    uint64_t bits64;
    uint32_t bits32[2];
    double num;
} Bits64;

#define CAPACITY_GROW_FACTOR 4
#define MIN_CAPACITY 64

bool ValueIsEqual(Value a, Value b);

#endif //VANTIDEL_CPP_CLASS_H
